<!-- 表单 -->
<template>
    <div class="form" v-loading="loading">
        <el-form :model="ruleForm" label-width="140px" inline ref="form" size="default">
            <el-form-item v-for="item in props.elForm_Options.wt_mesage" :key="item.prop" :label="item.label"
                :prop="item.prop" :required="item.required" :style="{ 'width': item.allwidth ? '100%' : '' }">
                <!-- input 输入框 -->
                <div v-if="item.paramtype == 'input'" class="item" :class="{ 'isEdit': isEdit(item) }">
                    <el-input v-if="isEdit(item)" v-model="ruleForm[item.prop]" />
                    <span v-else>{{ ruleForm[item.prop] }}</span>
                </div>
                <!-- select 下拉框 -->
                <div v-if="item.paramtype == 'select'" class="item" :class="{ 'isEdit': isEdit(item) }">
                    <el-select v-if="isEdit(item)" :value-key="item.props ? item.props.value : 'value'"
                        v-model="ruleForm[item.prop]" placeholder="请选择" clearable @change="v => changeselcet(v, item)"
                        :multiple="item.multiple">
                        <el-option v-for="(it, idx) in getoption(item)" :key="idx"
                            :label="getselectV(item, it, 'label')" :value="getselectV(item, it)" />
                    </el-select>
                    <div v-else>
                        <span v-if="item.multiple">
                            {{ multipleSelectShow(ruleForm[item.prop], getoption(item), item.props) }}
                        </span>
                        <span :style="getcolor(item)" v-else>
                            {{(getoption(item)).find(it1 => ruleForm[item.prop] ===
                                getselectV(item, it1)) != null ? (getoption(item)).find(it1 => ruleForm[item.prop] ===
                                    getselectV(item, it1))[(!item.props ? 'label' : item.props.value)] : ruleForm[item.prop]}}
                        </span>
                    </div>
                </div>
                <!-- time 时间 -->
                <div v-if="item.paramtype == 'time'" class="item" :class="{ 'isEdit': isEdit(item) }">
                    <el-date-picker v-if="isEdit(item)" v-model="ruleForm[item.prop]"
                        :type="item.type ? item.type : 'date'" clearable
                        @change="v => changedatapicker(v, item, ruleForm)" placeholder="选择日期" />
                    <span v-else>{{ commonV.formatDate(ruleForm[item.prop], !item.type ? "yyyy-MM-dd" : 'yyyy-MM-dd HH: mm: ss')
                        }}</span>
                </div>
                <!-- radio 单选框 -->
                <div v-if="item.paramtype == 'radio'" class="item" :class="{ 'isEdit': isEdit(item) }">
                    <el-radio :disabled="isEdit(item)" v-for="(it, idx) in item.radio" :key="idx"
                        v-model="ruleForm[item.prop]" :label="it">
                        {{ it }}
                    </el-radio>
                </div>
                <!-- checkbox 复选框 -->
                <div v-if="item.paramtype == 'checkbox'" class="item" :class="{ 'isEdit': isEdit(item) }">
                    <el-checkbox-group :disabled="flagIndex == 'detail' || item.disabled == true"
                        v-if="item.paramtype == 'checkbox'" v-model="ruleForm[item.prop]">
                        <el-checkbox v-for="(it, idx) in item.radio" :key="idx" :label="it" />
                    </el-checkbox-group>
                </div>
                <!-- upload 上传附件 -->
                <div v-if="item.paramtype == 'upload'" class="item" :class="{ 'isEdit': isEdit(item) }">
                    <el-upload v-if="isEdit(item)" class="upload-demo"
                        :on-change="(file, filesList) => filehandleChange(file, filesList, item.prop)"
                        :on-remove="(file, filesList) => filehandleChange(file, filesList, item.prop)"
                        :file-list="ruleForm[item.prop]" multiple :auto-upload="false" :on-exceed="handleExceed"
                        :limit="typeof item.limit == 'undefined' ? 9999999 : item.limit">
                        <div style="display: flex;margin:0 ;">
                            <img class="el-icon-plus" :src="iconPlus" />
                            <div style="color: #20A0FF;margin-left: 10px;font-size: 14px;">点击上传</div>
                        </div>
                    </el-upload>
                    <div v-else>
                        <div v-for="(it, idx) in ruleForm[item.prop]" :key="idx" class="downloada">
                            <a style="color: #20A0FF" :href="it.url" target="_blank">
                                {{ commonV.varfile(it.url) }}
                            </a>
                        </div>
                    </div>
                </div>
                <!-- textarea 文本框 -->
                <div v-if="item.paramtype == 'textarea'" class="item" :class="{ 'isEdit': isEdit(item) }">
                    <el-input v-if="isEdit(item)" v-model="ruleForm[item.prop]" type="textarea" autosize :rows="2">
                    </el-input>
                    <span v-else>{{ ruleForm[item.prop] }}</span>
                </div>
                <!-- imgupload 图片上传 -->
                <div v-if="item.paramtype == 'imgupload'" class="item" :class="{ 'isEdit': isEdit(item) }">
                    <div class="userimg_box" v-if="isEdit(item)">
                        <el-upload action="https://jsonplaceholder.typicode.com/posts/" list-type="picture-card"
                            :on-change="(file, filesList) => filehandleChange(file, filesList, item.prop)"
                            :on-remove="(file, filesList) => filehandleChange(file, filesList, item.prop)" multiple
                            :auto-upload="false" :file-list="ruleForm[item.prop]"
                            accept="image/jpeg,image/gif,image/png">
                            <el-icon>
                                <Plus />
                            </el-icon>
                        </el-upload>
                        <el-dialog :modal-append-to-body="false" :visible.sync="dialogVisible">
                            <img width="100%" :src="ruleForm[item.prop]" alt="" />
                        </el-dialog>
                    </div>
                    <div v-else>
                        <div v-if="flagIndex == 'detail' || item.disabled" style="display:flex;padding-top: 5px">
                            <div v-for="(it, idx) in changesrcList(ruleForm[item.prop])" :key="idx"
                                class="demo-image__preview">
                                <el-image style="width: 120px; height: 120px;margin-right:10px;" :src="it" fit="cover"
                                    :preview-src-list="changesrcList(ruleForm[item.prop])" />
                            </div>
                        </div>
                    </div>
                </div>
                <!-- 头像上传 avatarupload-->
                <div v-if="item.paramtype == 'avatarupload'" class="item" :class="{ 'isEdit': isEdit(item) }">
                    <el-upload class="avatar-uploader"
                        action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15" :show-file-list="false"
                        :on-change="changeAvatarSuccess" :auto-upload="false"
                        accept="image/jpeg,image/gif,image/png,image/jpg">
                        <img v-if="imageUrl" :src="imageUrl" class="avatar" />
                        <el-icon v-else class="avatar-uploader-icon">
                            <Plus />
                        </el-icon>
                    </el-upload>
                </div>
                <!-- number 数字框 -->
                <div v-if="item.paramtype == 'number'" class="item" :class="{ 'isEdit': isEdit(item) }">
                    <el-input-number v-if="isEdit(item)" v-model="ruleForm[item.prop]" :min="0"
                        @change="(currentValue, oldValue) => changeinputNumber(currentValue, oldValue, item, ruleForm)">
                    </el-input-number>
                    <span v-else>{{ ruleForm[item.prop] }}</span>
                </div>
                <!-- objectinkey 对象的值查看 -->
                <div v-if="item.paramtype == 'objectinkey'" class="item" :class="{ 'isEdit': isEdit(item) }">
                    <div v-if="isEdit(item)">
                        <el-input v-if="(ruleForm[item.keyName] && ruleForm[item.keyName][item.prop])"
                            v-model="ruleForm[item.keyName][item.prop]" />
                        <el-input v-else v-model="ruleForm[item.keyName]" />
                    </div>
                    <div v-else style="margin-left: 10px;">
                        {{
                            ruleForm[item.keyName] && ruleForm[item.keyName][item.prop] ? ruleForm[item.keyName][item.prop]
                                : ruleForm[item.keyName]
                        }}
                    </div>
                </div>
                <!-- cascader 级联选择器 -->
                <div v-if="item.paramtype == 'cascader'" class="item" :class="{ 'isEdit': isEdit(item) }">
                    <el-cascader clearable
                        :style="'width:' + (typeof item.width == 'undefined' ? '260px' : (item.width + 'px'))"
                        v-if="isEdit(item)" v-model="ruleForm[item.prop]" :placeholder="item.label"
                        :options="getoption(item)" />
                    <span v-else style="margin-left: 10px;">
                        {{ commonV.getCascaderFullValue(ruleForm[item.prop], item.options) }}</span>
                </div>
                <!-- 公共选择器多对多数组 -->
                <div v-for="(it2, in2) in manytomanyArr" :key="in2" style="width:100%">
                    <!-- 
                         chooseuser            人员多选  
                         chooserole            角色多选 
                         choosedepartment      选择科室  
                         arrangedepartment     指派科室  
                         choosedevice          选择设备   
                         chooselaboratory      选择试验室
                         choosedatabase        选择技术资料   
                        -->
                    <div v-if="item.paramtype == it2.paramtype" class="item" :class="{ 'isEdit': isEdit(item) }">
                        <div class="comommoretompre" v-if="isEdit(item)">
                            <div style="display: flex;align-items: center;">
                                <img style="cursor:pointer;line-height: normal;margin-right:20px;" :src="iconPlus"
                                    @click="common_event(it2, item)" />
                            </div>
                            <div v-if="ruleForm[item.prop]">
                                <el-tag style="margin:5px 10px 5px 0" :closable="item.closable !== false" type="info"
                                    v-for="(itmk1, ink1) in ruleForm[item.prop]" :key="ink1"
                                    @close="closetag(item.prop, ink1)">
                                    {{ itmk1[it2.key] }}
                                </el-tag>
                            </div>
                        </div>
                        <div style="margin-left: 10px" v-else>
                            <div :style="item.paramtype == 'choseapprove' ? 'color:#20A0FF;cursor:pointer' : ''">
                                {{ commonV.reverarr(ruleForm[item.prop], it2.key) }}
                            </div>
                        </div>
                    </div>
                </div>
            </el-form-item>
        </el-form>

        <!-- 公共弹框 -->
        <choose-component :choseData="choseData" ref="mychildchooseComponent" @inputsydata="inputsydata"
            v-if="modalStatus == '公共选择弹窗' && props.flagIndex != 'detail'" />
        <!-- 选择科室弹窗_Form -->
        <choose-department ref="mychoosedepartment" @inputdeparmentdata="inputdeparmentdata"
            v-if="modalStatus == '选择科室弹窗' && props.flagIndex != 'detail'" />
        <!-- 选择角色 -->
        <choose-role ref="mychooserole" v-if="modalStatus === '切换角色'" @submitHandle="submitHandle" />
    </div>
</template>

<script setup>
import { ref, reactive, toRefs, nextTick, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Session } from '@/utils/storage'
import commonV from '@/common/index'
import { useCach } from '@/store/cach'
import manytomanyData from '@/common/formConfig'
import { useRoute } from 'vue-router'
import api from '@/api'

const route = useRoute()

let props = defineProps({
    elForm_Options: {
        type: Object,
        default: () => {
            return {}
        }
    },
    flagIndex: {
        type: String,
        default: () => 'detail'
    }
})

let emits = defineEmits(['openBack', 'successdeal', 'changeinputNumber', 'chooseDataBackHandle'])

let pageConfig = useCach()

let modalStatus = computed(() => pageConfig.modalStatus)

//数据
let state = reactive({
    loading: false,
    ruleForm: {},
    UserMsg: Session.get('UserMsg'),
    iconPlus: commonV.require('@/assets/svg/addbutton.svg'),
    dialogVisible: false,
    manytomanyArr: manytomanyData,
    currentprop: '',
    choseData: null,
    imageUrl: ''
})
let {
    loading, ruleForm,
    iconPlus, dialogVisible,
    manytomanyArr, choseData,
    imageUrl
} = toRefs(state)

//实例
let form = ref()
let mychildchooseComponent = ref(null)
let mychoosedepartment = ref(null)
let mychooserole = ref(null)

//判断是否可编辑
let isEdit = (item) => {
    return props.flagIndex != 'detail' && (!item.disabled || state.UserMsg.is_superuser)
}

//获取配置项
let getoption = (item) => {
    return item.selfoption ? item.options : commonV.statusOption[item.options]
}

//切换下拉选项
let changeselcet = (v, item) => {
    console.log(v, item)
}

//下拉框多选时查看栏的显示
let multipleSelectShow = (arr, options, props) => {
    let ggd = ""
    if (commonV.ifvalidArr(arr)) {
        for (let index = 0; index < arr.length; index++) {
            const element = arr[index]
            let ccc = index == arr.length - 1 ? "" : ",";
            let itmk = options.find(it1 => parseInt(element) == parseInt((
                typeof props == 'undefined' ? it1.value : it1[props.value])))
            if (typeof itmk != 'undefined') {
                ggd += itmk[(typeof props == 'undefined' ? 'label' : props.label)] + ccc
            }
        }
    }
    return ggd
}

//获取下拉title
let getselectV = (item, item2, V = 'value') => {
    return (typeof item.props == 'undefined' ? item2[V] : item2[item.props[V]])
}

//获取颜色
let getcolor = (item) => {
    let color = '#1F2D3D'
    let V = getoption(item).find(item2 => state.ruleForm[item.prop] === getselectV(item, item2))
    if (V && V.color) {
        color = V.color
    }
    return 'color:' + color + '!important'
}

//切换日期
let changedatapicker = (v, item, ruleForm) => {
    console.log(v, item, ruleForm)
}

//图片上传改变
let filehandleChange = (file, filesList, prop) => {
    state.ruleForm[prop] = JSON.parse(JSON.stringify(filesList))
}

//图片上传限制
let handleExceed = () => {
    ElMessage({
        message: '当前限制选择 1 个文件',
        type: 'warning'
    })
}

//转换图片地址
let changesrcList = (imgArr = []) => {
    let srcList = []
    if (typeof imgArr != "undefined") {
        for (let index = 0; index < imgArr.length; index++) {
            const element = imgArr[index]
            srcList.push(element.url)
        }
    }
    return srcList
}

//切换头像触发
let changeAvatarSuccess = (file) => {
    state.ruleForm.avatar = file.raw
    state.imageUrl = URL.createObjectURL(file.raw)
}

//改变数字框
let changeinputNumber = (currentValue, oldValue, item, ruleForm) => {
    emits('changeinputNumber', currentValue, item, ruleForm)
}

//公共选择模板点击
let common_event = (item, obj) => {
    if (item.comname) {
        //有公共模板
        chooseCpt(obj, item.comname)
        return
    }
    otherClick(item.clickway, obj.prop)
}

//选择公共模板
let chooseCpt = (obj, comname) => {
    let prop = obj.prop
    state.currentprop = prop
    state.choseData = commonV.chooseComponent[comname] || []
    pageConfig.changeShowModal(true)
    pageConfig.changeModalStatus("公共选择弹窗")
    nextTick(() => {
        let res = []
        if (commonV.ifrrandnotnone(state.ruleForm[prop])) {
            res = JSON.parse(JSON.stringify(state.ruleForm[prop]))
        }
        mychildchooseComponent.value.openFunction(res, prop)
    })
}

//公共数据带回
let inputsydata = (selectArr = []) => {
    state.ruleForm[state.currentprop] = JSON.parse(JSON.stringify(selectArr))
    emits('chooseDataBackHandle', state.currentprop, selectArr, state.ruleForm)
}

//删除tag
let closetag = (prop, idx) => {
    state.ruleForm[prop].splice(idx, 1)
}

//有单独的事件
let otherClick = (way, prop) => {
    if (way === 'choosedepartment') {
        //选择科室
        choosedepartmentHandle(prop)
    } else if (way === 'chooserole') {
        //选择角色
        chooseroleHandle(prop)
    }
}

//选择科室
let choosedepartmentHandle = (prop) => {
    state.currentprop = prop
    let checked = false
    pageConfig.changeShowModal(true)
    pageConfig.changeModalStatus('选择科室弹窗')
    nextTick(() => {
        console.log(mychoosedepartment.value)
        mychoosedepartment.value?.openFunction(state.ruleForm[prop] ?
            state.ruleForm[prop] : null, prop, checked)
    })
}

//科室信息带回
let inputdeparmentdata = (selectedList = []) => {
    let roledata = []
    for (let index = 0; index < selectedList.length; index++) {
        const element = selectedList[index]
        roledata.push({
            id: element.id,
            department_name: element.department_tree_name ? element.department_tree_name : element.department_name
        })
    }
    state.ruleForm[state.currentprop] = roledata
}

//选择角色
let chooseroleHandle = (prop) => {
    state.currentprop = prop
    if (!state.ruleForm.role_ids) {
        state.ruleForm.role_ids = []
    }
    pageConfig.changeShowModal(true)
    pageConfig.changeModalStatus('切换角色')
    nextTick(() => {
        mychooserole.value.openFunction2(state.ruleForm[prop])
    })
}

//选择角色回调
let submitHandle = (title, selectedList) => {
    for (let index = 0; index < selectedList.length; index++) {
        const element = selectedList[index];
        if (typeof element.department != 'undefined') {
            if (element.department.id) {
                selectedList[index].department = element.department.id
            } else {
                selectedList[index].department = element.department
            }
        }
    }
    nextTick(() => {
        state.ruleForm[state.currentprop] = JSON.parse(JSON.stringify(selectedList))
        state.ruleForm.department_ids = commonV1.reverarr(selectedList, 'department')
    })
}

//获取form数据
let getFormData = async (params = {}) => {
    state.loading = true
    params.id = params.id ? params.id : route.params.id
    let res = await api.getaxiosdata(props.elForm_Options.getwayname, { id: params.id })
    if (res) {
        state.loading = false
        let results = typeof res.results == 'undefined' ? res[0] : res.results[0]
        state.ruleForm = results
        /* let objk = {
            api: props.elForm_Options.getwayname,
            method: 'get',
            res: results
        }
        this.successdeal(objk) */
        emits('openBack', results)
    }
}

//验证表单填写是否成功
let ifvalidate = async () => {
    return await form.value.validate((valid, error) => {
        if (valid) {
            return true
        }
        let notwritename = ""
        for (const key in error) {
            let it1 = props.elForm_Options.wt_mesage.find(item => item.prop == key)
            notwritename += (notwritename != "" ? "," : "") + it1.label
        }
        ElMessage({
            message: "请验证" + notwritename + "是否填写完毕且格式正确",
            type: "warning"
        })
        return false
    })
}

//提交表单数据
let submitFormData = async (param) => {
    let params = param ? param : { key: 'submitForm' }
    //先验证必填项
    let isPass = await ifvalidate()
    if (!isPass) return
    // 提示
    let titleStr = ''
    if (params?.key === 'submitForm') {
        //保存
        titleStr = '确定保存数据吗?'
    } else if (params?.key === 'commitForm') {
        //提交
        titleStr = '确定提交此次数据吗?'
    }

    //含有自定义文字
    if (params.customTxt) {
        titleStr = params.customTxt
    }

    ElMessageBox.confirm(
        titleStr,
        '提示',
        {
            confirmButtonText: '确 定',
            cancelButtonText: '取 消',
            type: 'warning',
        }
    ).then(() => {
        commitFormData(params)
    }).catch(() => { })
}

//走接口保存数据
let commitFormData = async (keys) => {
    state.loading = true
    //格式化表单数据
    let params = commonV.getwt_mesageValue(
        props.elForm_Options.wt_mesage,
        state.ruleForm
    )
    //额外参数
    let addConditions = props.elForm_Options.addConditions || []
    addConditions.forEach(it => {
        params.append(it.key, it.value)
    })

    let method = ''
    let url = props.elForm_Options.getwayname || ''
    if (props.flagIndex == 'create') {
        //新增
        method = "post"
        params.append("create_by", state.UserMsg.id)
        params.append("edit_by", state.UserMsg.id)
    } else if (props.flagIndex != 'create') {
        //修改或查看页提交
        method = "patch"
        params.append("id", keys.id ? keys.id : route.params.id)
        if (props.elForm_Options.editwayname) {
            url = props.elForm_Options.editwayname
        }
    }
    let res = await api.streamaxiosdata(url, method, params)
    if (res) {
        let objk = {
            api: url,
            method: method,
            res: res
        }
        let txt = ''
        if (props.flagIndex == 'create') {
            txt = '新增成功!'
        } else if (props.flagIndex == 'edit') {
            txt = '修改成功!'
        } else if (props.flagIndex == 'detail') {
            txt = '操作成功!'
        }
        //新增成功!
        ElMessage({
            message: txt,
            type: 'success'
        })
        emits('successdeal', objk)
    }
    state.loading = false
}

//设置表单数据
let setFormData = (formData) => {
    state.ruleForm = JSON.parse(JSON.stringify(formData))
}

defineExpose({ getFormData, submitFormData, setFormData, manytomanyArr: state.manytomanyArr })
</script>

<style lang="scss" scoped>
.form {
    background-color: #fff;
    padding: 10px;

    &:deep(.el-form-item) {
        width: 50%;
        display: flex;
        align-items: center;
        border-bottom: 1px solid #ccc;
        margin: 0;
        border-right: 1px solid #ccc;
        padding: 0 0 0 15px;
        background: #E5E9F2;
    }

    &:deep(.el-input__wrapper) {
        box-shadow: none;
    }

    .el-form {
        display: flex;
        flex-wrap: wrap;
        border-top: 1px solid #ccc;
    }

    &:deep(.el-form-item__label) {
        border-right: 1px solid #ccc;
    }

    &:deep(.el-form-item__content) {
        height: 100%;
    }

    .el-form-item__content .item {
        width: 100%;
        height: 100%;
        padding-left: 10px;
    }

    .isEdit {
        background-color: #fff;
    }

    &:deep(.el-form.el-form--inline .el-form-item--default.el-form-item:last-of-type, .el-form.el-form--inline .el-form-item--small.el-form-item:last-of-type) {
        margin-bottom: 0 !important;
    }

    &:deep(.el-select__wrapper) {
        box-shadow: none;
    }
}

.upload-demo {
    display: flex;
    justify-content: flex-start;
    flex-direction: column-reverse;

    &:deep(.el-upload-list) {
        margin: 0;
    }

    &:deep(.el-upload-list__item) {
        margin: 0;
    }

    &:deep(.el-upload) {
        justify-content: flex-start;
    }
}

.comommoretompre {
    display: flex;
    align-items: center;
    padding-left: 10px;
    min-height: 33.3px;
}

.avatar-uploader {
    display: flex;
    align-items: center;
    padding: 4px;

    &:deep(.el-upload) {
        border: 1px solid #ccc;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
        transition: var(--el-transition-duration-fast);
    }
}

.avatar-uploader .avatar {
    width: 120px;
    height: 120px;
    display: block;
}

.avatar-uploader .el-upload:hover {
    border-color: #409eff;
}

.el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 120px;
    height: 120px;
    text-align: center;
}
</style>